package com.futurescale.sa.model.vo
{
	/**
	 * A Chapter appears in one story only and groups
	 * a set of Scenes. This value object represents 
	 * one chapter and its associated scenes.
	 */
	[Bindable] 
	public class ChapterVO extends ValueObject
	{
		/**
		 * The XML element name.
		 */
		public static const ELEMENT:String = "Chapter";
			
		/**
		 * Construct a ChapterVO. 
		 */
		public function ChapterVO( xml:XML=null )
		{
			super( ELEMENT, xml );
			if (xml == null) getNewScene();
		}

		/** 
		 * An ordinal-sorted Vector of this Chapter's Scenes.
		 */
		public function get scenes():Vector.<SceneVO>
		{
			var v:Vector.<SceneVO> = new Vector.<SceneVO>();
			var xl:XMLList = xml.child(SceneVO.ELEMENT);
			for each ( var sx:XML in xl ) {
				var scene:SceneVO = new SceneVO(sx);
				v.push(scene);
			}
			v.sort(ValueObject.ordinalSort);
			return v;
		}
		public function set scenes( v:Vector.<SceneVO> ):void
		{} // read-only but bindable
		
		/**
		 * Get the text of the current Draft of all Scenes
		 * in this Chapter. The chapter name is included
		 * at the beginning of the text.
		 */
		public function getText( includeHeading:Boolean=false ):String
		{
			var t:String = includeHeading ? name + DOUBLE_SPACE : "";
			
			// all scenes at their current draft
			var sceneList:Vector.<SceneVO> = scenes;
			for each (var svo:SceneVO in sceneList) {
				var st:String = svo.getText();
				if (st != "") t += svo.getText(false) + DOUBLE_SPACE;
			}
			
			// read-only text of chapter
			return t;
		}
		
		/**
		 * Get a new Scene for the Chapter.
		 */
		public function getNewScene():SceneVO
		{
			var scene:SceneVO = new SceneVO();
			addScene(scene);
			return scene;
		}
		
		/**
		 * Add a Scene to the Chapter.
		 */
		public function addScene( scene:SceneVO ):void
		{
			// renumber scenes if inserting
			if ( scene.ordinal > 0 && scene.ordinal < nextSceneOrdinal ) {
				var scenes:Vector.<SceneVO> = this.scenes;
				for each ( var svo:SceneVO in scenes ){
					if ( svo.ordinal >= scene.ordinal ) svo.ordinal++;
				}
			} else {
				scene.ordinal = nextSceneOrdinal;
			}
			xml.appendChild( scene.xml );	
		}
		
		/** 
		 * Delete a Scene from the Chapter, renumbering
		 */
		public function deleteScene( scene:SceneVO  ):void
		{
			var sceneOrd:Number = scene.ordinal;
			delete xml..Scene.(@uid == scene.uid)[0];
			var scenes:Vector.<SceneVO> = this.scenes;
			for each (var svo:SceneVO in scenes ){
				if (svo.ordinal > sceneOrd) svo.ordinal--;
			}
		}
		
		/**
		 * Get the next Scene ordinal for this Chapter.
		 */
		private function get nextSceneOrdinal():Number
		{
			return getNextOrdinal( xml..Scene );
		}
	}
}